package cn.texous.util.commons.util;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

/**
 * insert description here.
 *
 * @author Showa.L
 * @since 2020/3/12 17:43
 */
public class ChineseUtils {

    @Getter
    @AllArgsConstructor
    public enum NumberType {
        NORMAL("1", "例：一千万零二百"),
        ELEMENT("2", "例：一二零零"),
        ;

        private String type;
        private String desc;

        public static final NumberType loadByType(String type) {
            return Stream.of(NumberType.values()).filter(nt -> nt.getType().equals(type))
                    .findAny()
                    .orElse(NumberType.NORMAL);
        }

    }

    /**
     * 将中文数字转换成阿拉伯数字，支持含有小数的数字
     *
     * @param string
     *            中文内容
     * @return
     */
    private static double parseChineseToDecimal(String string) {
        double result = 0.0;

        String str = string;
        // 计算小数部分
        int index = str.indexOf("点");
        if (index != -1) {
            // 如果“.”在最后一个字，则不作任何操作
            // 一般情况下，“.”不会在最后一个字
            if (index != str.length() - 1) {
                StringBuilder sb = new StringBuilder("0.");
                // 由于小数部分读法直接是读数字，而没有“十”、“百”、“千”、“万”、“亿”这些中文，所以需要一个个字进行翻译
                // 这里已经确定了有小数部分，且“点”字不是最后一位
                char[] decimal = str.split("点")[1].toCharArray();
                for (int i = 0; i < decimal.length; i++) {
                    sb.append((int) parseChineseToDecimal(String.valueOf(decimal[i])));
                }
                result += Double.parseDouble(sb.toString());
            }
            // 如果中文含有“点”字，重构整数部分
            str = str.substring(0, index);
        }

        // 计算整数部分
        str = str.replaceAll("零", "");
        index = str.lastIndexOf("亿");
        if (index != -1) {
            result += parseChineseToDecimal(str.substring(0, index)) * Math.pow(10.0, 8.0);
            if (index != str.length() - 1) {
                result += parseChineseToDecimal(str.substring(index + 1));
            }
        } else {
            index = str.lastIndexOf("万");
            if (index != -1) {
                result += parseChineseToDecimal(str.substring(0, index)) * Math.pow(10.0, 4.0);
                if (index != str.length() - 1) {
                    result += parseChineseToDecimal(str.substring(index + 1));
                }
            } else {
                index = str.lastIndexOf("千");
                if (index != -1) {
                    result += parseChineseToDecimal(str.substring(0, index)) * Math.pow(10.0, 3.0);
                    if (index != str.length() - 1) {
                        result += parseChineseToDecimal(str.substring(index + 1));
                    }
                } else {
                    index = str.lastIndexOf("百");
                    if (index != -1) {
                        result += parseChineseToDecimal(str.substring(0, index)) * Math.pow(10.0, 2.0);
                        // 如果“百”不是最后一个字，则应该加上后面的内容
                        if (index != str.length() - 1) {
                            result += parseChineseToDecimal(str.substring(index + 1));
                        }
                    } else {
                        index = str.lastIndexOf("十");
                        if (index != -1) {
                            // 当分解“十”时，需要对“十”开头的数据进行额外处理
                            if (index == 0) {
                                result += 10;
                                if (index != str.length() - 1) {
                                    result += parseChineseToDecimal(str.substring(index + 1));
                                }
                            } else {
                                result += parseChineseToDecimal(str.substring(0, index)) * 10.0;
                                if (index != str.length() - 1) {
                                    result += parseChineseToDecimal(str.substring(index + 1));
                                }
                            }
                        } else {
                            switch (str) {
                                case "零":
                                    result += 0.0;
                                    break;
                                case "一":
                                    result += 1.0;
                                    break;
                                case "二":
                                    result += 2.0;
                                    break;
                                case "三":
                                    result += 3.0;
                                    break;
                                case "四":
                                    result += 4.0;
                                    break;
                                case "五":
                                    result += 5.0;
                                    break;
                                case "六":
                                    result += 6.0;
                                    break;
                                case "七":
                                    result += 7.0;
                                    break;
                                case "八":
                                    result += 8.0;
                                    break;
                                case "九":
                                    result += 9.0;
                                    break;
                                default:
                                    result += 0.0;
                                    break;
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    private static final Map<String, String> NUMBER_MAP = new HashMap<>();
    static {
        NUMBER_MAP.put("一", "1");
        NUMBER_MAP.put("二", "2");
        NUMBER_MAP.put("三", "3");
        NUMBER_MAP.put("四", "4");
        NUMBER_MAP.put("五", "5");
        NUMBER_MAP.put("刘", "6");
        NUMBER_MAP.put("七", "7");
        NUMBER_MAP.put("八", "8");
        NUMBER_MAP.put("九", "9");
        NUMBER_MAP.put("零", "0");
        NUMBER_MAP.put("〇", "0");

    }

    public static Integer parseChineseToNumber(String string, NumberType numberType) {
        if (string == null)
            return null;
        if (NumberType.ELEMENT == numberType) {
            String[] numbers = string.split("");
            StringBuilder stringBuilder = new StringBuilder();
            Stream.of(numbers).forEach(n -> stringBuilder.append(NUMBER_MAP.get(n)));
            return Integer.valueOf(stringBuilder.toString());
        } else if (numberType.equals(NumberType.NORMAL)) {
            return Double.valueOf(parseChineseToDecimal(string)).intValue();
        }
        return null;
    }

    public static void main(String[] args) {
        String number = "一千九百二十五";
        String[] ns = number.split("");
        Stream.of(ns).forEach(System.out::println);
        System.out.println(parseChineseToDecimal(number));
    }

}
